package com.sutong.platform.service.impl;

import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sutong.common.result.ErrorCode;
import com.sutong.common.service.RemoteUserInterfaceInfoService;
import com.sutong.platform.constant.CommonConstant;
import com.sutong.platform.exception.BusinessException;
import com.sutong.platform.mapper.UserInterfaceInfoMapper;
import com.sutong.platform.model.dto.userinterfaceinfo.UserInterfaceInfoQueryRequest;
import com.sutong.platform.model.entity.InterfaceInfo;
import com.sutong.platform.model.entity.User;
import com.sutong.platform.model.entity.UserInterfaceInfo;
import com.sutong.platform.model.vo.InterfaceCallAnalysisVo;
import com.sutong.platform.service.InterfaceInfoService;
import com.sutong.platform.service.UserInterfaceInfoService;
import com.sutong.platform.service.UserService;
import com.sutong.platform.utils.SqlUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author sutong
 * @description 用户调用接口关系Service实现
 */
@Service
@DubboService(interfaceClass = RemoteUserInterfaceInfoService.class)
public class UserInterfaceInfoServiceImpl extends ServiceImpl<UserInterfaceInfoMapper, UserInterfaceInfo>
        implements UserInterfaceInfoService, RemoteUserInterfaceInfoService {

    @Resource
    private UserService userService;

    @Resource
    private InterfaceInfoService interfaceInfoService;

    @Resource
    private UserInterfaceInfoMapper userInterfaceInfoMapper;

    @Override
    public Wrapper<UserInterfaceInfo> getQueryWrapper(UserInterfaceInfoQueryRequest userInterfaceInfoQueryRequest) {
        if (userInterfaceInfoQueryRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空");
        }
        Long id = userInterfaceInfoQueryRequest.getId();
        Long userId = userInterfaceInfoQueryRequest.getUserId();
        Long interfaceInfoId = userInterfaceInfoQueryRequest.getInterfaceInfoId();
        Integer totalNum = userInterfaceInfoQueryRequest.getTotalNum();
        Integer leftNum = userInterfaceInfoQueryRequest.getLeftNum();
        Integer status = userInterfaceInfoQueryRequest.getStatus();
        String sortField = userInterfaceInfoQueryRequest.getSortField();
        String sortOrder = userInterfaceInfoQueryRequest.getSortOrder();
        QueryWrapper<UserInterfaceInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(ObjUtil.isNotNull(id), "id", id);
        queryWrapper.eq(ObjUtil.isNotNull(userId), "userId", userId);
        queryWrapper.eq(ObjUtil.isNotNull(interfaceInfoId), "interfaceInfoId", interfaceInfoId);
        queryWrapper.eq(ObjUtil.isNotNull(totalNum), "totalNum", totalNum);
        queryWrapper.eq(ObjUtil.isNotNull(leftNum), "leftNum", leftNum);
        queryWrapper.eq(ObjUtil.isNotNull(status), "status", status);
        queryWrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC), sortField);
        return queryWrapper;
    }

    /**
     * 调用接口次数+1
     *
     * @param userId
     * @param interfaceInfoId
     * @return
     */
    public Boolean callInterfaceCountByUserId(Long userId, Long interfaceInfoId) {
        // update userInterfaceInfo set letNum = letNum - 1, totalNum = totalNum + 1
        //      where userId = ? interfaceInfoId = ? and letNum > 0
        String key = userId + ":" + interfaceInfoId;
        synchronized (key.intern()) {
            return lambdaUpdate()
                    .setSql("letNum = letNum - 1, totalNum = totalNum + 1")
                    .eq(UserInterfaceInfo::getUserId, userId)
                    .eq(UserInterfaceInfo::getInterfaceInfoId, interfaceInfoId)
                    .gt(UserInterfaceInfo::getLeftNum, 0)
                    .update();
        }
    }

    @Override
    public Boolean callInterfaceCount(String accessKey, Long interfaceInfoId) {
        User user = userService.lambdaQuery().eq(User::getAccessKey, accessKey).one();
        if (ObjectUtil.isNull(user)) {
            return false;
        }
        return callInterfaceCountByUserId(user.getId(), interfaceInfoId);
    }

    /**
     * 查看top10接口调用情况
     */
    @Override
    public List<InterfaceCallAnalysisVo> callAnalysis() {
        int limit = 10;
        List<InterfaceCallAnalysisVo> result = userInterfaceInfoMapper.callAnalysis(limit);
        Map<Long, InterfaceCallAnalysisVo> map = result.stream().collect(Collectors.toMap(InterfaceCallAnalysisVo::getInterfaceInfoId, v -> v));
        List<InterfaceInfo> interfaceInfos = interfaceInfoService
                .lambdaQuery()
                .select(InterfaceInfo::getId, InterfaceInfo::getName)
                .in(InterfaceInfo::getId, map.keySet())
                .list();
        return interfaceInfos.stream().map(interfaceInfo -> {
            InterfaceCallAnalysisVo interfaceCallAnalysisVo = map.get(interfaceInfo.getId());
            interfaceCallAnalysisVo.setName(interfaceInfo.getName());
            return interfaceCallAnalysisVo;
        }).collect(Collectors.toList());
    }

    @Override
    public Long selectTotalNumSum() {
        return userInterfaceInfoMapper.selectTotalNumSum();
    }
}




